package pres.man.interview.producerconsumer.much;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 多生产者多消费者模型
 * 使用Semaphore实现
 *
 * @author MAN
 * @date 2020-12-07 21:16
 * @project
 * @since
 */
public class SemaphoreDo {
    private static final ThreadPoolExecutor POOL = new ThreadPoolExecutor(5, 8, 20, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10), new ThreadPoolExecutor.CallerRunsPolicy());

    public static void main(String[] args) {
        SemaphoreDo lockAndCondition = new SemaphoreDo();
        for (int i = 0; i < 5; i++) {
            POOL.execute(() -> {
                for (; ; ) {
                    lockAndCondition.son();
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            POOL.execute(() -> {
                for (; ; ) {
                    lockAndCondition.daughter();
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            POOL.execute(() -> {
                for (; ; ) {
                    lockAndCondition.mom();
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            POOL.execute(() -> {
                for (; ; ) {
                    lockAndCondition.dad();
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

    }


    /**
     * 盘子
     */
    private static final Semaphore PLATE = new Semaphore(1);
    private static final Semaphore APPLE = new Semaphore(0);
    private static final Semaphore ORANGE = new Semaphore(0);


    /**
     * 只往盘子里放苹果
     */
    public void mom() {
        try {
            PLATE.acquire();
            System.out.println("mom往盘子里面放一个苹果");
            TimeUnit.SECONDS.sleep(1);
            APPLE.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {

        }
    }

    /**
     * 只往盘子里放橘子
     */
    public void dad() {
        try {
            PLATE.acquire();
            System.out.println("dad往盘子里面放一个橘子");
            TimeUnit.SECONDS.sleep(1);
            ORANGE.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        }
    }


    /**
     * 只吃苹果
     */
    public void son() {
        try {
            APPLE.acquire();
            System.out.println("son吃掉一个苹果");
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            PLATE.release();
        }
    }

    /**
     * 只吃橘子
     */
    public void daughter() {
        try {
            ORANGE.acquire();
            System.out.println("daughter吃掉一个橘子");
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            PLATE.release();
        }
    }
}
